package com.shop.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.shop.common.SetMeta;
import com.shop.common.page.GoodPage;
import com.shop.config.ThumbnailsUtils;
import com.shop.entity.Attr;
import com.shop.entity.Attribute;
import com.shop.entity.Good;
import com.shop.entity.Pic;
import com.shop.exception.GoodException;
import com.shop.mapper.AttributeMapper;
import com.shop.mapper.GoodAttrMapper;
import com.shop.mapper.GoodMapper;
import com.shop.mapper.PicMapper;
import com.shop.service.GoodService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class GoodServiceImpl implements GoodService {

    @Autowired
    private GoodMapper goodMapper;

    @Autowired
    private AttributeMapper attributeMapper;

    @Autowired
    private PicMapper picMapper;

    @Autowired
    private GoodAttrMapper goodAttrMapper;

    /**
     * 商品列表数据
     * @param pagenum
     * @param pagesize
     * @return
     */
    @Override
    public SetMeta selectPageGood(String query, Integer pagenum, Integer pagesize) throws GoodException {
        if(pagenum <= 0 || pagesize < 0) throw new GoodException("参数错误");
        SetMeta setMeta = new SetMeta();
        Page<Good> goodPage = goodMapper.selectPage(new Page<>(pagenum, pagesize)
                    , Wrappers.<Good>lambdaQuery().like(Good::getGoods_name, query).select(Good.class, i -> !i.getColumn().equals("cat_id")
                            && !i.getColumn().equals("goods_introduce") && !i.getColumn().equals("goods_big_logo")
                            && !i.getColumn().equals("goods_small_logo") && !i.getColumn().equals("is_del")
                            && !i.getColumn().equals("delete_time") && !i.getColumn().equals("cat_one_id")
                            && !i.getColumn().equals("cat_two_id") && !i.getColumn().equals("cat_three_id")));

        setMeta.setSuccess(new GoodPage((int) goodPage.getTotal(), pagenum, goodPage.getRecords()));

        return setMeta;
    }

    /**
     * 添加商品
     * @param good
     * @return
     */
    @Override
    public SetMeta insertGood(Good good) throws GoodException {
        // 判断不可为空参数是否为空
        if(good.getGoods_name() == null || good.getGoods_name().equals("") || good.getGoods_cat() == null || good.getGoods_cat().equals("") || good.getGoods_price() == null || good.getGoods_price().equals("") || good.getGoods_number() == null || good.getGoods_number().equals("") || good.getGoods_weight() == null || good.getGoods_weight().equals(""))
            throw new GoodException("参数错误");

        SetMeta setMeta = new SetMeta();

        good.setAddTime((int) new Date().getTime());
        good.setUpdTime((int) new Date().getTime());
        int insert = goodMapper.insert(good);
        if(insert != 1) throw new GoodException("创建商品失败");

        // 将分类参数进行转换封装
        setCatId(good);
        // 将商品图片进行转换封装
        good.setPics(setPics(good.getGoods_id(), good.getPics()));
        // 将商品参数进行转换封装
        good.setAttrs(setAttrs(good.getGoods_id(), good.getAttrs()));

        // 将商品图片和参数存入数据库
        good.setPics(insertPic(good.getPics()));
        good.setAttrs(insertAttr(good.getAttrs()));

        int update = goodMapper.update(good, Wrappers.<Good>lambdaQuery().eq(Good::getGoods_id, good.getGoods_id()));
        if(update != 1) throw new GoodException("创建商品失败");
        Good select = goodMapper.selectById(good.getGoods_id());

        good.setGoodsBigLogo("");
        good.setGoodsSmallLogo("");
        good.setCatOneId(null);
        good.setCatTwoId(null);
        good.setCatThreeId(null);
        good.setHotMumber(select.getHot_mumber());
        good.setIsPromote(select.getIs_promote());
        good.setGoodsState(select.getGoods_state());
        setMeta.setCreated(good,"创建商品成功");

        return setMeta;
    }

    /**
     * 根据Id查询商品
     * @param id
     * @return
     */
    @Override
    public SetMeta selectGood(Integer id) throws GoodException {
        Good good = goodMapper.selectById(id);
        if(good == null) throw new GoodException("查询商品失败");
        good.setPics(getPic(id));
        getAttr(good);

        // 设置不需要的参数为空
        good.setCatId(null);
        good.setIsDel(null);

        SetMeta setMeta = new SetMeta();
        setMeta.setSuccess(good,"查找商品成功");

        return setMeta;
    }

    /**
     * 编辑商品信息
     * @param good
     * @return
     * @throws GoodException
     */
    @Override
    public SetMeta updateGood(Good good) throws GoodException {
        if(good.getGoods_name() == null || good.getGoods_name().equals("") || good.getGoods_price() == null || good.getGoods_price().equals("") || good.getGoods_number() == null || good.getGoods_number().equals("") || good.getGoods_weight() == null || good.getGoods_weight().equals(""))
            throw new GoodException("商品相关参数为空");

        SetMeta setMeta = new SetMeta();

        good.setPics(setPics(good.getGoods_id(), good.getPics()));

        int update = goodMapper.update(good, Wrappers.<Good>lambdaQuery().eq(Good::getGoods_id, good.getGoods_id()));
        if(update != 1) throw new GoodException("更新商品失败");

        updatePic(good.getGoods_id(), good.getPics());
        updateAttr(good.getGoods_id(), good.getAttrs());

        good.setPics(getPic(good.getGoods_id()));

        getAttr(good);

        setMeta.setSuccess(good, "更新商品成功");


        return setMeta;
    }

    /**
     * 删除商品
     * @param id
     * @return
     */
    @Override
    public SetMeta deleteGood(Integer id) throws GoodException {
        SetMeta setMeta = new SetMeta();
        int delete = goodMapper.delete(Wrappers.<Good>lambdaQuery().eq(Good::getGoods_id, id));
        picMapper.delete(Wrappers.<Pic>lambdaQuery().eq(Pic::getGoods_id, id));
        goodAttrMapper.delete(Wrappers.<Attr>lambdaQuery().eq(Attr::getGoods_id, id));
        if(delete == 0) throw new GoodException("删除商品失败");

        setMeta.setSuccess("删除商品成功");
        return setMeta;
    }

    /**
     * 商品分类列表封装
     * @param good
     * @throws GoodException
     */
    private void setCatId(Good good) throws GoodException {
        String[] cat = good.getGoods_cat().split(",");
        good.setGoodsCat(null);
        switch (cat.length) {
            case 1:
                good.setCatId(Integer.parseInt(cat[0]));
                good.setCatOneId(Integer.parseInt(cat[0]));
                break;
            case 2:
                good.setCatId(Integer.parseInt(cat[1]));
                good.setCatOneId(Integer.parseInt(cat[0]));
                good.setCatTwoId(Integer.parseInt(cat[1]));
                break;
            case 3:
                good.setCatId(Integer.parseInt(cat[2]));
                good.setCatOneId(Integer.parseInt(cat[0]));
                good.setCatTwoId(Integer.parseInt(cat[1]));
                good.setCatThreeId(Integer.parseInt(cat[2]));
                break;
            default:
                throw new GoodException("商品分类参数级别错误");
        }
    }

    /**
     * 商品图片进行转换封装
     * @param goods_id
     * @param pics
     */
    private List<Pic> setPics(Integer goods_id,List<Pic> pics) throws GoodException {
        List<Pic> picList = new ArrayList<>();
        for (Pic pic : pics) {
            if (pic.getPics_id() == null) {
                Pic newPic = new Pic();
                String picMsg = pic.getPic().split("/")[1];
                newPic.setGoodsId(goods_id);
                newPic.setPicsBig("uploads/goodspics/big_" + picMsg);
                newPic.setPicsMid("uploads/goodspics/mid_" + picMsg);
                newPic.setPicsSma("uploads/goodspics/sma_" + picMsg);
                picList.add(newPic);
            }
        }
        upload(picList);
        return picList;
    }

    /**
     * 图片插入数据库
     * @param pics
     * @throws GoodException
     */
    private List<Pic> insertPic(List<Pic> pics) throws GoodException {
        List<Pic> newPic = new ArrayList<>();
        for (Pic pic : pics) {
            if (pic.getPics_id() == null) {
                picMapper.insert(pic);
            }
            newPic.add(pic);
        }
        return newPic;
    }

    /**
     * 商品分类参数进行转换封装
     * @Param goods_id
     * @param attrs
     * @throws GoodException
     */
    private List<Attr> setAttrs(Integer goods_id,List<Attr> attrs) throws GoodException {
        for (Attr attr : attrs) {
            if (attr.getGoods_id() == null) {
                Attribute attribute = attributeMapper.selectById(attr.getAttr_id());
                if (attribute == null) throw new GoodException("商品参数不存在");
                attr.setGoodsId(goods_id);
                attr.setAttrId(attribute.getAttr_id());
                attr.setAttrName(attribute.getAttr_name());
                attr.setAttrSel(attribute.getAttr_sel());
                attr.setAttrWrite(attribute.getAttr_write());
                attr.setAttrVals(attribute.getAttr_vals());
            }
        }
        return attrs;
    }

    /**
     * 商品分类参数插入数据库
     * @param attrs
     * @throws GoodException
     */
    private List<Attr> insertAttr(List<Attr> attrs) throws GoodException {
        for (Attr attr : attrs) {
            goodAttrMapper.insert(attr);
        }
        return attrs;
    }

    /**
     * 获取商品图片信息进行封装
     * @param id
     */
    private List<Pic> getPic(Integer id) {
        return picMapper.selectList(Wrappers.<Pic>lambdaQuery().eq(Pic::getGoods_id, id));

    }

    /**
     * 获取商品参数信息进行封装
     * @param good
     */
    private void getAttr(Good good) {
        List<Attr> attrs = goodAttrMapper.selectList(Wrappers.<Attr>lambdaQuery().eq(Attr::getGoods_id, good.getGoods_id()));
        List<Attribute> attributes = attributeMapper.selectList(null);
        for (Attr attr : attrs) {
            for (Attribute attribute : attributes) {
                if (attr.getAttr_id().equals(attribute.getAttr_id())) {
                    attr.setAttrName(attribute.getAttr_name());
                    attr.setAttrSel(attribute.getAttr_sel());
                    attr.setAttrWrite(attribute.getAttr_write());
                    attr.setAttrVals(attribute.getAttr_vals());
                    break;
                }
            }
        }
        good.setAttrs(attrs);
    }

    /**
     * 修改商品图片信息
     * @param goods_id
     * @param pics
     */
    private void updatePic(Integer goods_id, List<Pic> pics) throws GoodException {
        List<Pic> picLists = picMapper.selectList(Wrappers.<Pic>lambdaQuery().eq(Pic::getGoods_id, goods_id));
        List<Pic> insertList = new ArrayList<>();
        List<Pic> updateList = new ArrayList<>();
        List<Pic> deleteList = new ArrayList<>();

        if (pics.size() < picLists.size()) {
            for (Pic picList : picLists) {
                boolean flag = true;
                for (Pic pic : pics) {
                    if (pic.getPics_id() == null) {
                        insertList.add(pic);
                        flag = false;
                        break;
                    } else if (pic.getPics_id().equals(picList.getPics_id())) {
                        updateList.add(pic);
                        flag = false;
                        break;
                    }
                }
                if (flag) {
                    deleteList.add(picList);
                }
            }
        } else {
            for (Pic pic : pics) {
                boolean flag = true;
                Pic newPic = new Pic();
                if (pic.getPics_id() == null) {
                    insertList.add(pic);
                    flag = false;
                    break;
                } else {
                    for (Pic picList : picLists) {
                        if (pic.getPics_id().equals(picList.getPics_id())) {
                            updateList.add(pic);
                            flag = false;
                            break;
                        } else {
                            newPic = picList;
                        }
                    }
                }
                if (flag) {
                    deleteList.add(newPic);
                }
            }
        }

        insertPic(insertList);
        updatePic(updateList);
        deletePic(deleteList);


    }

    /**
     * 修改商品参数信息
     * @param goods_id
     * @param attrs
     */
    private void updateAttr(Integer goods_id, List<Attr> attrs) throws GoodException {
        List<Attr> attrsList = goodAttrMapper.selectList(Wrappers.<Attr>lambdaQuery().eq(Attr::getGoods_id, goods_id));
        List<Attr> insertList = new ArrayList<>();
        List<Attr> updateList = new ArrayList<>();
        List<Attr> deleteList = new ArrayList<>();

        if (attrs.size() < attrsList.size()) {
            for (Attr attrList : attrsList) {
                boolean flag = true;
                for (Attr attr : attrs) {
                    if (attr.getGoods_id() == null) {
                        insertList.add(attr);
                        flag = false;
                        break;
                    } else if (attr.getId().equals(attrList.getId())) {
                        updateList.add(attr);
                        flag = false;
                        break;
                    }
                }
                if (flag) {
                    deleteList.add(attrList);
                }
            }
        } else {
            for (Attr attr : attrs) {
                boolean flag = true;
                Attr newAttr = new Attr();
                for (Attr attrList : attrsList) {
                    if (attr.getGoods_id() == null) {
                        insertList.add(attr);
                        flag = false;
                        break;
                    } else if (attr.getId().equals(attrList.getId())) {
                        updateList.add(attr);
                        flag = false;
                        break;
                    } else {
                        newAttr = attrList;
                    }
                }
                if (flag) {
                    deleteList.add(newAttr);
                }
            }
        }

        insertList = setAttrs(goods_id, insertList);
        insertAttr(insertList);
        updateAttr(updateList);
        deleteAttr(deleteList);
    }

    /**
     * 修改商品图片信息
     * @param pics
     */
    private void updatePic(List<Pic> pics) throws GoodException {
        for (Pic pic : pics) {
            picMapper.update(pic, Wrappers.<Pic>lambdaQuery().eq(Pic::getPics_id, pic.getPics_id()));
        }
    }

    /**
     * 删除商品图片信息
     * @param pics
     */
    private void deletePic(List<Pic> pics) throws GoodException {
        for (Pic pic : pics) {
            picMapper.delete(Wrappers.<Pic>lambdaQuery().eq(Pic::getPics_id, pic.getPics_id()));
        }
    }

    /**
     * 修改商品参数信息
     * @param attrs
     * @throws GoodException
     */
    private void updateAttr(List<Attr> attrs) throws GoodException {
        for (Attr attr : attrs) {
            goodAttrMapper.update(attr, Wrappers.<Attr>lambdaQuery().eq(Attr::getId, attr.getId()));
        }
    }

    /**
     * 删除商品参数信息
     * @param attrs
     * @throws GoodException
     */
    private void deleteAttr(List<Attr> attrs) throws GoodException {
        for (Attr attr : attrs) {
            goodAttrMapper.delete(Wrappers.<Attr>lambdaQuery().eq(Attr::getId, attr.getId()));
        }
    }

    private void upload(List<Pic> pics) throws GoodException {
        for (Pic pic : pics) {
            try {
                File file = new File("D:/tmp_uploads/" + pic.getPics_big().split("/")[2].split("_")[1]);
                BufferedImage image = ImageIO.read(file);
                BufferedImage bigImage = ThumbnailsUtils.resizeImageOne(image, 800, 800);
                BufferedImage midImage = ThumbnailsUtils.resizeImageOne(image, 400, 400);
                BufferedImage smaImage = ThumbnailsUtils.resizeImageOne(image, 200, 200);
                ImageIO.write(bigImage, "jpg", new File("D:/" + pic.getPics_big()));
                ImageIO.write(midImage, "jpg", new File("D:/" + pic.getPics_mid()));
                ImageIO.write(smaImage, "jpg", new File("D:/" + pic.getPics_sma()));
            } catch (Exception e) {
                throw new GoodException("上传失败");
            }
        }
    }

}
